import type { App } from 'vue';
import { createRouter, createWebHashHistory } from 'vue-router';
import { useTitle } from '@vueuse/core';
import { constantRoutes } from './staticRoutes';
import { usePermissionStoreWithOut } from '@/plugins/pinia/modules/permission';
import { useUserStoreWithOut } from '@/plugins/pinia/modules/user';

export const router = createRouter({
  history: createWebHashHistory(),
  routes: constantRoutes,
  strict: true,
  scrollBehavior: () => ({ left: 0, top: 0 })
});

export const resetRouter = () => {
  const resetWhiteNameList = ['Redirect', 'Login', 'NoFind', 'Root'];
  router.getRoutes().forEach((route) => {
    const { name } = route;
    if (name && !resetWhiteNameList.includes(name as string)) {
      router.hasRoute(name) && router.removeRoute(name);
    }
  });
};

const registerRoutes = (...routes) => {
  routes.flat().forEach((route) => {
    const { name } = route;
    if (name && !router.hasRoute(name)) {
      router.addRoute(route);
    }
  });
};

// 不重定向白名单
const whiteList = ['/login'];

router.beforeEach((to, from, next) => {
  if (whiteList.includes(to.path)) {
    next();
  } else {
    const userStore = useUserStoreWithOut();
    if (!userStore.getToken) {
      next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`);
    } else if (to.path === '/login') {
      next('/');
    } else {
      const permissionStore = usePermissionStoreWithOut();
      if (permissionStore.isLoadedRoutes) {
        next();
      } else {
        permissionStore
          .generateRoutes('frontEnd', [])
          .then((routes) => {
            registerRoutes(routes);
            permissionStore.setIsLoadedRoutes(true);
            const redirectPath = from.query.redirect || to.path;
            const redirect = decodeURIComponent(redirectPath as string);
            const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
            next(nextData);
          })
          .catch(() => {
            next(`/login?redirect=${to.path}`);
          });
      }
    }
  }
});

router.afterEach((to) => {
  useTitle(to?.meta?.title as string);
});

export default function (app: App) {
  app.use(router);
}
